@@ -40,7 +40,6 @@ module Agents |
||
40 | 40 |
def check |
41 | 41 |
api = DropboxAPI.new(interpolated[:access_token]) |
42 | 42 |
current_contents = api.dir(interpolated[:dir_to_watch]) |
43 |
- |
|
44 | 43 |
diff = DropboxDirDiff.new(previous_contents, current_contents) |
45 | 44 |
create_event(payload: diff.to_hash) unless previous_contents.nil? || diff.empty? |
46 | 45 |
|
@@ -66,13 +65,32 @@ module Agents |
||
66 | 65 |
# == Auxiliary classes == |
67 | 66 |
|
68 | 67 |
class DropboxAPI |
68 |
+ class ResourceNotFound < RuntimeError; end |
|
69 |
+ |
|
70 |
+ include HTTParty |
|
71 |
+ base_uri 'https://api.dropbox.com/1' |
|
72 |
+ |
|
69 | 73 |
def initialize(access_token) |
74 |
+ @options = { query: { access_token: access_token } } |
|
75 |
+ end |
|
76 |
+ |
|
77 |
+ def dir(to_watch) |
|
78 |
+ options = @options.deep_merge({ query: { list: true } }) |
|
79 |
+ response = self.class.get("/metadata/auto#{to_watch}", options) |
|
80 |
+ raise ResourceNotFound.new(to_watch) if response.not_found? |
|
81 |
+ JSON.parse(response)['contents'].map { |entry| slice_json(entry, :path, :rev, :modified) } |
|
82 |
+ end |
|
83 |
+ |
|
84 |
+ private |
|
85 |
+ |
|
86 |
+ def slice_json(json, *keys) |
|
87 |
+ keys.each_with_object({}){|key, hash| hash[key] = json[key.to_s]} |
|
70 | 88 |
end |
71 | 89 |
end |
72 | 90 |
|
73 | 91 |
class DropboxDirDiff |
74 | 92 |
def initialize(previous, current) |
75 |
- @previous, @current = [previous, current] |
|
93 |
+ @previous, @current = [previous || [], current || []] |
|
76 | 94 |
end |
77 | 95 |
|
78 | 96 |
def empty? |
@@ -154,6 +154,88 @@ describe Agents::DropboxWatchAgent do |
||
154 | 154 |
expect(diff_hash[:updated]).to eq [ { path: '1.json', rev: '2' } ] |
155 | 155 |
end |
156 | 156 |
|
157 |
+ context 'when the previous value is not defined' do |
|
158 |
+ it 'considers all additions' do |
|
159 |
+ diff_hash = Agents::DropboxWatchAgent::DropboxDirDiff.new(nil, current).to_hash |
|
160 |
+ expect(diff_hash[:added]).to eq current |
|
161 |
+ expect(diff_hash[:removed]).to eq [] |
|
162 |
+ expect(diff_hash[:updated]).to eq [] |
|
163 |
+ end |
|
164 |
+ end |
|
165 |
+ |
|
166 |
+ context 'when the current value is not defined' do |
|
167 |
+ it 'considers all removals' do |
|
168 |
+ diff_hash = Agents::DropboxWatchAgent::DropboxDirDiff.new(previous, nil).to_hash |
|
169 |
+ expect(diff_hash[:added]).to eq [] |
|
170 |
+ expect(diff_hash[:removed]).to eq previous |
|
171 |
+ expect(diff_hash[:updated]).to eq [] |
|
172 |
+ end |
|
173 |
+ end |
|
174 |
+ end |
|
175 |
+ end |
|
176 |
+ |
|
177 |
+ describe Agents::DropboxWatchAgent::DropboxAPI do |
|
178 |
+ let(:dir_to_watch) { '/my/dropbox/dir' } |
|
179 |
+ let(:access_token) { '70k3n' } |
|
180 |
+ let(:api_url) { "https://api.dropbox.com/1/metadata/auto#{dir_to_watch}?access_token=#{access_token}&list=true" } |
|
181 |
+ |
|
182 |
+ describe '#dir' do |
|
183 |
+ |
|
184 |
+ context 'when the provided path exists' do |
|
185 |
+ before do |
|
186 |
+ stub_request(:get, api_url).to_return(body: JSON.dump({ |
|
187 |
+ contents: [ |
|
188 |
+ { |
|
189 |
+ bytes: 0, |
|
190 |
+ icon: "folder", |
|
191 |
+ is_dir: true, |
|
192 |
+ modified: "Mon, 11 Mar 2013 15:41:44 +0000", |
|
193 |
+ path: "#{dir_to_watch}/1.json", |
|
194 |
+ rev: "1", |
|
195 |
+ revision: 14743, |
|
196 |
+ root: "dropbox", |
|
197 |
+ size: "0 bytes", |
|
198 |
+ thumb_exists: false |
|
199 |
+ }, |
|
200 |
+ { |
|
201 |
+ bytes: 0, |
|
202 |
+ icon: "folder", |
|
203 |
+ is_dir: true, |
|
204 |
+ modified: "Mon, 12 Mar 2013 15:41:44 +0000", |
|
205 |
+ path: "#{dir_to_watch}/2.json", |
|
206 |
+ rev: "4", |
|
207 |
+ revision: 113022, |
|
208 |
+ root: "dropbox", |
|
209 |
+ size: "0 bytes", |
|
210 |
+ thumb_exists: false |
|
211 |
+ } |
|
212 |
+ ], |
|
213 |
+ some: "other", |
|
214 |
+ things: "we", |
|
215 |
+ dont: "need" |
|
216 |
+ })) |
|
217 |
+ end |
|
218 |
+ |
|
219 |
+ it 'trims down the attributes of the response to our needs' do |
|
220 |
+ dir_list = Agents::DropboxWatchAgent::DropboxAPI.new(access_token).dir(dir_to_watch) |
|
221 |
+ expect(dir_list).to eq [ |
|
222 |
+ { path: "#{dir_to_watch}/1.json", rev: '1', modified: 'Mon, 11 Mar 2013 15:41:44 +0000' }, |
|
223 |
+ { path: "#{dir_to_watch}/2.json", rev: '4', modified: 'Mon, 12 Mar 2013 15:41:44 +0000' } |
|
224 |
+ ] |
|
225 |
+ end |
|
226 |
+ end |
|
227 |
+ |
|
228 |
+ context 'when the provided path does not exist' do |
|
229 |
+ before { stub_request(:get, api_url).to_return(status: 404, body: '{"error": "Not Found"}') } |
|
230 |
+ |
|
231 |
+ it 'raises a ResourceNotFound error' do |
|
232 |
+ expect { |
|
233 |
+ Agents::DropboxWatchAgent::DropboxAPI.new(access_token).dir(dir_to_watch) |
|
234 |
+ }.to raise_error(Agents::DropboxWatchAgent::DropboxAPI::ResourceNotFound, dir_to_watch) |
|
235 |
+ end |
|
236 |
+ end |
|
237 |
+ |
|
157 | 238 |
end |
239 |
+ |
|
158 | 240 |
end |
159 | 241 |
end |